package com.easylinkin.linkappapi.taskscheduler.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.lobar.mapper.UserProjectMapper;
import com.easylinkin.linkappapi.taskscheduler.entity.JobEntity;
import com.easylinkin.linkappapi.taskscheduler.entity.UserAreaDTO;
import com.easylinkin.linkappapi.taskscheduler.entity.UserAreaVO;
import com.easylinkin.linkappapi.taskscheduler.service.JobEntityService;
import com.easylinkin.linkappapi.taskscheduler.service.TaskSchedulerService;
import com.easylinkin.linkappapi.taskscheduler.service.UserAreaResetService;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.sevice.LinkappTenantService;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class UserAreaResetServiceImpl implements UserAreaResetService, Job {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserAreaResetServiceImpl.class);

    private static final String PREFIX = "userAreaReset";

    private static final String AREALIST = "areaList";

    private static final String TENANTID = "tenantId";

    private static final String RESETTIME = "resetTime";

    private static final String ENABLED = "enabled";

    @Autowired
    LinkappTenantService linkappTenantService;

    @Autowired
    TaskSchedulerService taskSchedulerService;

    @Autowired
    JobEntityService jobEntityService;

    @Autowired
    UserProjectMapper userProjectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTask(UserAreaVO userAreaVO) {
        validateParam(userAreaVO);
        JobEntity jobEntity = new JobEntity();
        initial(userAreaVO, jobEntity);
        taskSchedulerService.saveTask(jobEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTask(UserAreaVO userAreaVO) {
        validateParam(userAreaVO);
        JobEntity originJobEntity = queryJobEntity();
        initial(userAreaVO, originJobEntity);
        taskSchedulerService.updateTask(originJobEntity);
        //若设置为禁用（jobStatus=“0”），则暂停定时任务；为启用则开启该定时任务
        if(originJobEntity.getJobStatus().equals("0")) {
            taskSchedulerService.pause(originJobEntity);
        }
        if(originJobEntity.getJobStatus().equals("1")) {
            taskSchedulerService.resume(originJobEntity);
        }
    }

    @Override
    public UserAreaVO queryTask() throws ParseException {
        JobEntity originJobEntity = queryJobEntity();
        if(originJobEntity != null) {
            UserAreaVO userAreaVO = new UserAreaVO();
            String parmString = originJobEntity.getParams();
            JSONObject parmObject = (JSONObject) JSONObject.parse(parmString);
            List<String> areaList = (List<String>) parmObject.get(AREALIST);
            String resetArea = String.join(",", areaList);
            userAreaVO.setResetArea(resetArea);
            SimpleDateFormat format = new SimpleDateFormat("HH:mm");
            userAreaVO.setResetTime(format.parse((String) parmObject.get(RESETTIME)));
            userAreaVO.setEnabled((String) parmObject.get(ENABLED));
            return userAreaVO;
        }
        return null;
    }

//    @Override
//    public void testReset(UserAreaVO userArea) {
//        UserAreaDTO userAreaDTO = new UserAreaDTO();
//        userAreaDTO.setTenantId("5a920f536428050edddcce5212f36a97");
//        List<String> areaList = new ArrayList<String>();
//        areaList.add("4");
//        userAreaDTO.setAreaList(areaList);
//        userAreaDTO.setArea("1");
//        userAreaDTO.setModifyTime(new Date());
//        userProjectMapper.updateAreaByTenantId(userAreaDTO);
//    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        LOGGER.info("进入userAreaReset-execute");
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        String jobName = jobDetail.getKey().getName();
        String jobGroup = jobDetail.getKey().getGroup();
        LOGGER.info("userAreaReset-定时任务开始，任务分组：{}，任务名称：{}，任务触发时间：{}",
                jobGroup, jobName, DateUtil.getYYYYMMDDHHMMSSDate(new Date()));
        String parmString = jobDetail.getJobDataMap().getString("params");
        JSONObject parmObject = (JSONObject) JSONObject.parse(parmString);

        UserAreaDTO userAreaDTO = new UserAreaDTO();
        userAreaDTO.setAreaList((List<String>) parmObject.get(AREALIST));
        userAreaDTO.setTenantId((String) parmObject.get(TENANTID));
        userAreaDTO.setModifyTime(new Date());

        userProjectMapper.updateAreaByTenantId(userAreaDTO);

        LOGGER.info("userAreaReset-定时任务结束，任务分组：{}，任务名称：{}，任务结束时间：{}",
                jobGroup, jobName, DateUtil.getYYYYMMDDHHMMSSDate(new Date()));
    }

    private String getTenatId() {
        LinkappTenant currentTenant = linkappTenantService.currentTenant();
        Assert.notNull(currentTenant, "当前租户为空");
        Assert.notNull(currentTenant.getProjectId(), "当前租户项目id为空");
        String tenatId = currentTenant.getId();
        return tenatId;
    }

    private void validateParam(UserAreaVO userAreaVO) {
        Assert.notNull(userAreaVO, "参数为空");
        Assert.notNull(userAreaVO.getResetArea(), "重置区域为空");
        Assert.notNull(userAreaVO.getResetTime(), "重置时间为空");
        Assert.notNull(userAreaVO.getEnabled(), "是否禁用为空");
    }

    private void initial(UserAreaVO userAreaVO, JobEntity jobEntity) {
        String[] strs = userAreaVO.getResetArea().split(",");
        List<String> list = Arrays.asList(strs);
        JSONObject parmObject = new JSONObject();
        String teantId = getTenatId();
        parmObject.put(AREALIST, list);
        parmObject.put(TENANTID, teantId);
        parmObject.put(RESETTIME, userAreaVO.getResetTime());
        parmObject.put(ENABLED, userAreaVO.getEnabled());
        String parmString = JSON.toJSONStringWithDateFormat(parmObject, "HH:mm");
        String jobGroup = PREFIX + "_" + teantId;
        String jobName = UUID.randomUUID().toString().replaceAll("-", "");
        //获取指定任务时间的24小时制时分秒
        String[] strDate = new SimpleDateFormat("HH:mm").format(userAreaVO.getResetTime()).toString().split(":");
        //按照时分秒构建CRON表达式，每日定时执行
        //时间格式调整，去除前缀0，例如00->0,01->1
        String minutes = String.valueOf(Integer.parseInt(strDate[1]));
        String hours = String.valueOf(Integer.parseInt(strDate[0]));
        String cronExpression = "0 " + minutes + " " + hours + " " + "1/1 * ?";

        Date date = new Date();
        //更新时不修改以下字段
        if(jobEntity.getJobName() == null) {
            jobEntity.setJobName(jobName);
            jobEntity.setJobGroup(jobGroup);
            jobEntity.setCreateTime(date);
            jobEntity.setJobClassName(this.getClass().getName());
            jobEntity.setIsNowRun("0");//不立刻运行
            jobEntity.setJobTaskType("1");//存储过程
            jobEntity.setJobType("0");//周期运行
        }

        jobEntity.setCronExpression(cronExpression);
        jobEntity.setModifyTime(date);
        jobEntity.setJobStatus(userAreaVO.getEnabled());
        jobEntity.setParams(parmString);
    }

    private JobEntity queryJobEntity() {
        //查询原有Job，一个项目下仅有一个区域人数重置任务，因此使用job_group查询
        String teantId = getTenatId();
        String jobGroup = PREFIX + "_" + teantId;
        QueryWrapper<JobEntity> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("job_group",jobGroup);
        JobEntity originJobEntity=jobEntityService.getOne(queryWrapper);
        return originJobEntity;
    }
}
